package com.lwl.mini.util;

import com.lwl.mini.builder.BuilderException;
import lombok.Data;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author lwl
 * @create 2022/4/12 10:38
 */
@Data
public class ResolverUtils<T> {

    /**
     * 存放类信息
     */
    private Set<Class<? extends T>> matches = new HashSet<>();

    private ClassLoader classLoader;


    /**
     * @param packageName 包的类路径
     */
    public ResolverUtils<T> find(String packageName){
        String packagePath = getPackagePath(packageName);
        List<String> children =  LoadingUtils.getInstance().list(packagePath);
        for(String child:children){
            if(child.endsWith(".class")){
                addIfMatching(child);
            }
        }
        return this;
    }

    /**
     * @param packageName 类路径
     * @return 可查找路径,如com/lwl/test...
     */
    public String getPackagePath(String packageName){
        return packageName == null?null:packageName.replace('.','/');
    }

    /**
     * 将.class文件装进match数组中
     */
    public void addIfMatching(String path){
        try {
            String externalName = path.substring(0,path.indexOf('.')).replace('/','.');
            ClassLoader loader = getClassLoader();
            Class<?> aClass = loader.loadClass(externalName);
            if(aClass!=null){
                matches.add((Class<T>) aClass);
            }
        }catch (Exception e){
            throw new BuilderException("类加载失败:"+e,e);
        }
    }

    /**
     * @return 返回一个类加载器，如果位置的类加载器，则返回默认的类加载器
     */
    public ClassLoader getClassLoader() {
        return classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
    }
}
